---@param Sheet Csharp.Sheet
return function(Sheet)
    local lists = {}

    if Sheet.LastRowNum < 4 then
        return lists
    end
    local mergeRow = Sheet:GetRow(0)
    local keyRow = Sheet:GetRow(2)

    local idName = keyRow:GetCell(1).StringCellValue

    for y = 3, Sheet.LastRowNum do
        local dataRow = Sheet:GetRow(y)
        local name = dataRow:GetCell(1).StringCellValue

        if name == '' then goto skip end

        local data = {}
        local mergeCount = 0
        local clear_is_list = {}

        for x = 2, dataRow.LastCellNum do
            local merge = mergeRow:GetCell(x).StringCellValue
            ---@type any
            local key = keyRow:GetCell(x).StringCellValue
            local cell = dataRow:GetCell(x)
            local value

            if merge:find 'color' == nil then
                if cell.TypeCode == 0 or cell.NumericCellValue > 0 then
                    value = cell.NumericCellValue
                else
                    value = cell.StringWar3
                end
            else
                value = cell.StringWar3
            end

            if type(value) == 'string' then
                value = value:gsub('\n', '|n')
            end

            value = FormatTargetType(key, value)

            if merge:find 'table' and value ~= '' then
                value = LineToTable(value)
            end

            if merge == '' and key == '' and value ~= '' then
                value = LineToTable(value)
                for k, v in pairs(value) do
                    data[k] = v
                end
                value = ''
            end

            if merge:find '[%[{]' then
                local pattern_start = merge:find '=%[' and '=%[' or '={'
                local pattern_end = merge:find '=%[' and ']' or '}'

                local function addMergeData(startIndex, count)
                    local tab = {}
                    for t = 0, count do
                        local key2 = keyRow:GetCell(startIndex + t).StringCellValue
                        ---@type any
                        local cell2 = dataRow:GetCell(startIndex + t)
                        local value2
                        if cell2.TypeCode == 0 then
                            value2 = cell2.NumericCellValue
                        else
                            value2 = cell2.StringCellValue
                        end
                        local mergeData2 = mergeRow:GetCell(startIndex + t).StringCellValue
                        if type(value2) == 'string' then
                            value2 = value2:clear_color()
                        end
                        if value2 == '' then
                            value2 = nil
                        elseif value2 and mergeData2:find 'table' then
                            value2 = LineToTable(value2)
                        end
                        if key2 ~= '' then
                            tab[key2] = value2
                        else
                            table.insert(tab, value2)
                        end
                    end
                    return tab
                end

                mergeCount, key = MergeFunc(x, mergeRow, pattern_start, pattern_end)
                local tab = addMergeData(x, mergeCount)

                if data[key] then
                    if data[key].is_list then
                        data[key][#data[key] + 1] = tab
                    else
                        data[key] = { is_list = true, data[key], tab }
                        clear_is_list[key] = true
                    end
                else
                    if next(tab) then
                        data[key] = tab
                    end
                end
                mergeCount = mergeCount + 1
            end

            if mergeCount > 0 then
                mergeCount = mergeCount - 1
                goto Merge
            end


            if value ~= '' then
                if key == '' then
                    data[y] = value
                else
                    data[key] = value
                end
            end

            :: Merge ::
        end

        for key in pairs(clear_is_list) do
            data[key].is_list = nil
        end

        if next(data) then
            data[idName] = name
            table.insert(lists, { key = #lists + 1, value = data })
        end

        :: skip ::
    end

    return lists
end
